package com.example.springcloudribbonclient.server.impl;

import com.example.springcloudribbonclient.server.ClientServer;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.concurrent.Future;

@Service
public class ClientServerimpl implements ClientServer {


    //负载均衡工具
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public String client() {
        //通过负载均衡算法之后得到的URL实例
//        ServiceInstance si  = loadBalancerClient.choose("ribbon-project");  //大小写不敏感
//        System.out.println("getURL:" + si.getHost());
//        System.out.println("getPort:" +si.getPort());
//        System.out.println("getUri:" +si.getUri());
//        System.out.println("getServiceId:" +si.getServiceId());
//        System.out.println("getMetadata:" +si.getMetadata());
//        System.out.println("getInstanceId:" +si.getInstanceId());
//        System.out.println("getScheme:" +si.getScheme());

        String result = restTemplate.getForObject("http://ribbon-project/ribbon",String.class);
        return result;
    }


    @HystrixCollapser(batchMethod = "mybatch", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
                       collapserProperties = {
                               @HystrixProperty(name="timerDelayInMilliseconds",value="100")
                       }
    )
    @Override
    public Future<String> clientHystrix(String name) {
        /**
         * 请求合并的方法恒不会执行
         */
        System.out.println("请求合并的方法恒不会被执行_廖钒_Get?怎么还是执行了?没有跳转到mybatch?");
        System.out.println("原因是什么?");
        ServiceInstance si = loadBalancerClient.choose("ribbon-project");
        RestTemplate restTemplate = new RestTemplate();
        //System.out.println(si.getUri()+ "/feignWithHystrixCollasperList?name=" + name);
        String result = restTemplate.getForObject(si.getUri()+ "/feignWithHystrixCollasper?name=1",String.class);
        return null;
    }

    @HystrixCommand(groupKey = "evangelionvr", commandKey = "thread", threadPoolKey = "evangelionvr", threadPoolProperties = {
            @HystrixProperty(name="coreSize",value="8"),
            @HystrixProperty(name="maxQueueSize",value="5"),
            @HystrixProperty(name="queueSizeRejectionThreshold",value="5")
    })
    @Override
    public String thread1() {
        System.out.println(Thread.currentThread().getName());
        return null;
    }

    @HystrixCommand(groupKey = "evangelionvr-VR", commandKey = "thread", threadPoolKey = "evangelionvr-VR", threadPoolProperties = {
            @HystrixProperty(name="coreSize",value="8"),
            @HystrixProperty(name="maxQueueSize",value="5"),
            @HystrixProperty(name="queueSizeRejectionThreshold",value="5")
    })
    @Override
    public String thread2() {
        System.out.println(Thread.currentThread().getName());
        return null;
    }

    @HystrixCommand
    public List<String> mybatch(List<String> names) {
        System.out.println("进入请求合并方法:" + names);
        ServiceInstance si = loadBalancerClient.choose("ribbon-project");
        RestTemplate restTemplate = new RestTemplate();
        List list = restTemplate.postForObject(si.getUri() + "/feignWithHystrixCollasperList",names,List.class);
        return list;
    }


    @HystrixCommand(commandProperties = {
            @HystrixProperty(name= HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS,value="10"),
            @HystrixProperty(name=HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,value="SEMAPHORE")
    },fallbackMethod = "semaphoreFallBackMethod")
    @Override
    public String semaphore() {
        System.out.println("执行了信号量隔离");
        try {
            Thread.sleep(900);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "正常执行";
    }

    @HystrixCommand
    public String semaphoreFallBackMethod() {
        System.out.println("semaphoreFallBackMethod降级");
        return null;
    }
}
